package com.bsg.upm.service;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.cache.DefinitionMetricCache;
import com.bsg.upm.cache.DefinitionMetricClassCache;
import com.bsg.upm.constant.MonitorCommonMap;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.entity.DefinitionMetricClassEntity;
import com.bsg.upm.entity.DefinitionMetricEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;

/**
 * 
 * @author yucs
 *
 */



@Service
public class TemplateConfigService extends BaseService {
	@Resource
	private DefinitionMetricCache definitionMetricCache;

	@Resource
	private DefinitionMetricClassCache definitionMetricClassCache;

	public RespJson enableEvent(String siteId, String metric) throws APIException {

		String urlPattern = "/{0}/template/event/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metric);
		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, null);

		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("enableEvent fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson disableEvent(String siteId, String metric) throws APIException {

		String urlPattern = "/{0}/template/event/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metric);
		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, null);

		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("disableEvent fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();

	}

	public RespJson enbleEventLevel(String siteId, String metric, String level) throws APIException {
		JSONObject paramJson = new JSONObject();
		paramJson.put("level", level);

		String urlPattern = "/{0}/template/event/level/{1}/enable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("enbleEventLevel fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson disableEventLevel(String siteId, String metric, String level) throws APIException {
		JSONObject paramJson = new JSONObject();
		paramJson.put("level", level);

		String urlPattern = "/{0}/template/event/level/{1}/disable";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("disableEventLevel fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson updateEvent(String siteId, String metric, String level, String start, String end)
			throws APIException {
		JSONObject paramJson = new JSONObject();

		paramJson.put("level", level);
		paramJson.put("start", start);
		paramJson.put("end", end);

		String urlPattern = "/{0}/template/level/{1}";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metric);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("updateEvent fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson getMetricCleanDay(String siteId) throws APIException {

		String urlPattern = "/{0}/monitor/clean";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);
		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("getMetricCleanDay fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}
		JSONObject obj = new JSONObject();
		obj.put("monitor_time", ((JSONObject) httpRespJson.getData()).getInteger("time"));

		return RespJsonFactory.buildOK(obj);
	}

	public RespJson updateMetricCleanDay(String siteId, int days) throws APIException {
		JSONObject paramJson = new JSONObject();
		paramJson.put("clean_time", days);

		String urlPattern = "/{0}/monitor/cleanup";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION);

		RespJson httpRespJson = sendHttpPost(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("updateMetricCleanDay fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson getEventCleanDay(String siteId) throws APIException {

		String urlPattern = "/{0}/event/clean";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION);

		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);
		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("getEventCleanDay fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}
		JSONObject obj = new JSONObject();
		obj.put("event_time", ((JSONObject) httpRespJson.getData()).getInteger("time"));

		return RespJsonFactory.buildOK(obj);
	}

	private boolean isHttp2XX(int status) {
		if (status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED) {
			return true;
		}
		return false;
	}

	public RespJson updateEventCleanDay(String siteId, int days) throws APIException {
		JSONObject paramJson = new JSONObject();
		paramJson.put("clean_time", days);

		String urlPattern = "/{0}/event/cleanup";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION);

		RespJson httpRespJson = sendHttpPost(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());
		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("updateEventCleanDay fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	public RespJson updateMetricClassIntervalTime(String siteId, String metricClass, int time) throws APIException {
		JSONObject paramJson = new JSONObject();
		paramJson.put("interval_time", time);

		String urlPattern = "/{0}/template/intervaltime/{1}";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION, metricClass);

		RespJson httpRespJson = sendHttpPut(siteId, SysConstants.INTERFACE_TYPE_HS, url, paramJson.toJSONString());

		if (!isHttp2XX(httpRespJson.getStatus())) {
			logger.error("updateMetricClassIntervalTime fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return RespJsonFactory.buildOK();
	}

	private JSONArray getHorusTemplates(String siteId) throws APIException {
		String urlPattern = "/{0}/template";
		String url = MessageFormat.format(urlPattern, SysConstants.HS_VERSION);
		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_HS, url);

		if (httpRespJson.getStatus() != HttpStatus.SC_OK) {
			logger.error("getHorusTemplates fail:" + httpRespJson);
			throw new APIException(httpRespJson.getMsg());
		}

		return (JSONArray) httpRespJson.getData();
	}

	private JSONObject getMetricClassShowObject(DefinitionMetricClassEntity definitionMetricClass,
			JSONObject metricClass) {
		JSONObject mectricClassObj = new JSONObject();

		mectricClassObj.put("name", definitionMetricClass.getName());
		mectricClassObj.put("description", definitionMetricClass.getDescription());
		mectricClassObj.put("metric_class", definitionMetricClass.getMetricClass());

		if (metricClass != null) {
			mectricClassObj.put("interval_time", metricClass.getString("interval_time"));
			mectricClassObj.put("enabled", metricClass.getBoolean("enable"));
		}

		return mectricClassObj;
	}

	private JSONObject getEventTemplateShowObject(DefinitionMetricEntity definitionMetric, JSONObject event) {
		JSONObject eventObj = new JSONObject();

		String metricName = definitionMetric.getDescription();
		eventObj.put("metric", definitionMetric.getMetric());
		eventObj.put("metric_name", metricName);

		if (eventObj != null) {
			eventObj.put("start", event.getString("start"));
			eventObj.put("end", event.getString("end"));

			eventObj.put("event_level_enable", event.getBoolean("event_level_enable"));
			eventObj.put("event_enable", event.getBoolean("event_enable"));
			eventObj.put("alarm_enable", event.getBoolean("alarm_enable"));

			eventObj.put("event_history", event.getBoolean("event_history"));
			eventObj.put("event_counter", event.getInteger("event_counter"));

			String levelName = MonitorCommonMap.getLevelName(event.getString("level"));
			eventObj.put("level", event.getString("level"));
			eventObj.put("level_name", levelName);

			String eventName = metricName + ":" + levelName + "类";
			eventObj.put("event_name", eventName);

			String eventDescription = metricName + "的" + levelName + "等级";
			eventObj.put("event_description", eventDescription);
		}

		return eventObj;
	}

	private Map<String, JSONObject> getMetricMap(String siteId) throws APIException {
		JSONArray templates = getHorusTemplates(siteId);

		Map<String, JSONObject> maps = new HashMap<String, JSONObject>();

		for (Object metricclass : templates) {
			JSONArray metrics = ((JSONObject) metricclass).getJSONArray("metrics");

			for (Object tmp : metrics) {
				JSONObject metric = (JSONObject) tmp;
				maps.put(metric.getString("metric"), metric);
			}

		}

		return maps;
	}

	private Map<String, JSONObject> getMetricClassMap(String siteId) throws APIException {
		JSONArray templates = getHorusTemplates(siteId);

		Map<String, JSONObject> maps = new HashMap<String, JSONObject>();

		for (Object metricClass : templates) {
			String metricClassName = ((JSONObject) metricClass).getString("metric_class");
			maps.put(metricClassName, (JSONObject) metricClass);

		}

		return maps;
	}

	public RespJson getMetricClassTemplate(String siteId) throws APIException {
		JSONArray templates = new JSONArray();

		List<DefinitionMetricClassEntity> dfMetrics = definitionMetricClassCache.listDfMetricClassFromCache();
		if (dfMetrics.size() <= 0) {
			return RespJsonFactory.buildOK(templates);
		}

		Map<String, JSONObject> maps = getMetricClassMap(siteId);

		for (DefinitionMetricClassEntity dfMetric : dfMetrics) {
			JSONObject metricClass = maps.get(dfMetric.getMetricClass());
			JSONObject mectricClassObj = getMetricClassShowObject(dfMetric, metricClass);
			templates.add(mectricClassObj);
		}

		return RespJsonFactory.buildOK(templates);
	}

	public RespJson getEventTemplate(String siteId) throws APIException {

		JSONArray eventTemplates = new JSONArray();

		List<DefinitionMetricEntity> dfMetrics = definitionMetricCache.listDfMetricFromCache();
		if (dfMetrics.size() <= 0) {
			return RespJsonFactory.buildOK(eventTemplates);
		}

		Map<String, JSONObject> eventMaps = getMetricMap(siteId);
		for (DefinitionMetricEntity dfMetric : dfMetrics) {

			if (!dfMetric.isEventShowEnabled()) {
				continue;
			}

			JSONObject metric = eventMaps.get(dfMetric.getMetric());
			if (metric == null) {
				continue;
			}

			for (Object tmp : metric.getJSONArray("event_levels")) {
				JSONObject event = (JSONObject) tmp;

				event.put("event_enable", metric.getBoolean("event"));
				event.put("event_history", metric.getBoolean("history"));
				event.put("event_counter", metric.getInteger("counter"));

				JSONObject eventObj = getEventTemplateShowObject(dfMetric, event);

				eventTemplates.add(eventObj);
			}

		}

		return RespJsonFactory.buildOK(eventTemplates);

	}

}
